package server;

import classloader.ModuleManager;
import classloader.MyClassLoaderByClass;
import com.myservlet.HttpServlet;
import org.dom4j.*;
import org.dom4j.io.SAXReader;

import java.io.File;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

public class Config {


    public static List<Service> services;

    public static void init() {
        System.out.println("初始化开始...");
        if(services==null) {
            services = new ArrayList<>();
        }

        InputStream resourceAsStream = Config.class.getClassLoader().getResourceAsStream("server.xml");
        SAXReader saxReader = new SAXReader();
        try {
            Document document = saxReader.read(resourceAsStream);
            Element rootElement = document.getRootElement();

            List<Element> serviceElements = rootElement.selectNodes("//Service");
            List<Element> connectorElements = rootElement.selectNodes("//Connector");
            List<Element> engineElements = rootElement.selectNodes("//Engine");
            List<Element> hostElements = rootElement.selectNodes("//Host");

            for(Element serviceElement : serviceElements) {
                Service service = new Service();
                for (Element connectorElement : connectorElements) {
                    if(connectorElement.getParent().equals(serviceElement)) {
                        service.port = Integer.parseInt(connectorElement.attributeValue("port"));
                    }
                }
                if(service.hosts==null) service.hosts = new ArrayList<>();
                for (Element engineElement : engineElements) {
                    if(engineElement.getParent().equals(serviceElement)) {
                        for (Element hostElement : hostElements) {
                            if(hostElement.getParent().equals(engineElement)) {
                                Mapper.Host host = new Mapper.Host(
                                        hostElement.attributeValue("name"),
                                        hostElement.attributeValue("appBase"),
                                        loadContexts(hostElement.attributeValue("appBase")));
                                service.hosts.add(host);

                            }
                        }
                    }
                }
                services.add(service);
            }

            System.out.println("初始化完成...");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static List<Mapper.Context> loadContexts(String appBase) throws Exception {
        List<Mapper.Context> contextList = new ArrayList<>();
        File root = new File(appBase);
        for (File demoRoot : root.listFiles()) { // 遍历各个项目
            // 先加载jar包
            File[] jars = new File(demoRoot.getAbsolutePath() + "/WEB-INF/lib").listFiles();
            List<String> jarList = new ArrayList<>();
            for (File jar : jars) {
                jarList.add(jar.getAbsolutePath());
            }
            ModuleManager manager = new ModuleManager();
            manager.setModuleList(jarList);
            manager.init();

            URL[] urls= new URL[jars.length];
            for(int i =0;i<jars.length;i++) {
                urls[i] = jars[i].toURI().toURL();
            }

            // 加载class
            MyClassLoaderByClass myClassLoaderByClass = new MyClassLoaderByClass(
                    demoRoot.getAbsolutePath() + "/WEB-INF/classes/",
                    urls,
                    manager
            );

            Mapper.Context context = new Mapper.Context();
            context.name = demoRoot.getName();

            // 加载servlet
            context.wrappers = loadWrappers(myClassLoaderByClass, demoRoot);
            contextList.add(context);
        }
        return contextList;
    }

    private static List<Mapper.Wrapper> loadWrappers(MyClassLoaderByClass myClassLoaderByClass, File demoRoot) throws Exception {
        List<Mapper.Wrapper> wrapperList = new ArrayList<>();
        SAXReader saxReader = new SAXReader();


        try {
            Document document = saxReader.read(new File(demoRoot.getAbsolutePath()+"/WEB-INF/web.xml"));
            Element rootElement = document.getRootElement();

            List<Element> selectNodes = rootElement.selectNodes("//servlet");
            for (int i = 0; i < selectNodes.size(); i++) {
                Element element =  selectNodes.get(i);
                // <servlet-name>lagou</servlet-name>
                Element servletnameElement = (Element) element.selectSingleNode("servlet-name");
                String servletName = servletnameElement.getStringValue();
                // <servlet-class>server.LagouServlet</servlet-class>
                Element servletclassElement = (Element) element.selectSingleNode("servlet-class");
                String servletClass = servletclassElement.getStringValue();


                // 根据servlet-name的值找到url-pattern
                Element servletMapping = (Element) rootElement.selectSingleNode("/web-app/servlet-mapping[servlet-name='" + servletName + "']");
                // /lagou
                String urlPattern = servletMapping.selectSingleNode("url-pattern").getStringValue();
                Object servlet = myClassLoaderByClass.loadClass(servletClass).newInstance();
                Mapper.Wrapper wrapper = new Mapper.Wrapper();
                wrapper.name = urlPattern;
                wrapper.object = servlet;
                wrapperList.add(wrapper);

            }
            return wrapperList;


        } catch (DocumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }
}
